package com.ds.lens.data.service.esservice;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Lists;
import com.ds.lens.data.common.document.ForecastData;
import com.ds.lens.data.common.query.ESQueryAdaptor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Properties;

import static com.alibaba.druid.pool.DruidDataSourceFactory.PROP_CONNECTIONPROPERTIES;
import static com.alibaba.druid.pool.DruidDataSourceFactory.PROP_URL;

/**
 * Description:
 *
 * @author WeiShaoying
 * @date 2020-05-10
 */
@Slf4j
@Service
public class ForecastDataService {

    @Value("${elasticsearch.jdbc.url}")
    private String esJDBCUrl;

    @Value("${elasticsearch.forecast-data.index}")
    private String forecastDataIndex;

    private ESQueryAdaptor esQueryAdaptor;

    @PostConstruct
    public void init() {
        try {
            Properties properties = new Properties();
            properties.put(PROP_URL, esJDBCUrl);
            properties.put(PROP_CONNECTIONPROPERTIES, "client.transport.ignore_cluster_name=true");
            esQueryAdaptor = new ESQueryAdaptor(properties);
            esQueryAdaptor.connect();
        } catch (Exception e) {
            log.error("error occurred.", e);
        }
    }

    @PreDestroy
    public void cleanup() {
        try {
            if (esQueryAdaptor != null) {
                esQueryAdaptor.close();
            }
        } catch (Exception e) {
            log.error("error occurred.", e);
        }
    }

    public List<ForecastData> queryForecastDatas(Long monitorId, Integer version, Long startTime, Long endTime) {
        StringBuilder sql = new StringBuilder("select * from ").append(forecastDataIndex)
                .append(" where monitorId=").append(monitorId)
                .append(" and version=").append(version)
                .append(" and ts between ").append(startTime)
                .append(" and ").append(endTime).append(" order by ts desc");
//        long limit = ((endTime - startTime) / 60000);
        sql.append(" limit 5000");
        try {
            List<Map<String, Object>> list = esQueryAdaptor.query(sql.toString(), null);
            if (CollectionUtils.isEmpty(list)) {
                return Collections.emptyList();
            }
            List<ForecastData> forecastData = Lists.newArrayListWithCapacity(list.size());
            list.forEach(map -> forecastData.add(JSONObject.parseObject(JSON.toJSONString(map), ForecastData.class)));
            return forecastData;
        } catch (Exception e) {
            log.error("error occurred. while query sql: " + sql, e);
            return Collections.emptyList();
        }
    }

}
